﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.Search;
using Lucene.Net.Store;
using Directory = Lucene.Net.Store.Directory;
using Version = Lucene.Net.Util.Version;

namespace LuceneWrap.Lib
{
    public class LuceneManagerOld
    {

        private readonly string _INDEX_FILEPATH = ConfigurationManager.AppSettings.Get("LuceneIndexFilePath");

        private Analyzer _analyzer = null;
        private IndexWriter _indexWriter = null;
        private IndexReader _indexReader = null;
        private Directory _luceneIndexDirectory = null;
        private int _totalCountDocuments = 0;


        
        public LuceneManagerOld()
        {
            Create();
        }

        public LuceneManagerOld(string indexFilePath):this()
        {
            _INDEX_FILEPATH = indexFilePath;
        }

        private void Create()
        {
            _analyzer = new StandardAnalyzer(Version.LUCENE_29);
            _luceneIndexDirectory = FSDirectory.Open(new DirectoryInfo(_INDEX_FILEPATH));
            _indexWriter = new IndexWriter(_luceneIndexDirectory, _analyzer, IndexWriter.MaxFieldLength.UNLIMITED);
            _indexReader = IndexReader.Open(_luceneIndexDirectory, false);
            _totalCountDocuments = _indexReader.MaxDoc();
            _indexReader.Close();
        }

        #region Insert index

        #region Public methods

        public void AddItemToIndex<T>(T field) where T : BasicField
        {
            AddFieldToIndex(field);
            FinalizeWriter(true);
        }

        public void AddItemsToIndex<T>(List<T> fields) where T : BasicField
        {
            foreach (var field in fields)
            {
                AddFieldToIndex(field);
            }
            FinalizeWriter(true);
        }

        #endregion

        #region Private methods
        

        private void AddFieldToIndex<T>(T field) where T: BasicField
        {
            Document document = new Document();
            var newField = MapElementToLuceneField(field);
            document.Add(newField);
            _indexWriter.AddDocument(document);
        }

        #endregion

        #endregion

        #region UpdateIndex

        #region Public methods

        public void ModifyItemFromIndex<T>(T oldField, T newField) where T : BasicField
        {
            DeleteFieldFromIndex(oldField);
            InsertUpdateFieldFromIndex(newField);
            FinalizeWriter(false);
        }

        public void ModifyItemFromIndex<T>(List<T> oldField, List<T> newField) where T : BasicField
        {
            foreach (var field in oldField)
            {
                DeleteFieldFromIndex(field);
            }
            foreach (var field in newField)
            {
                InsertUpdateFieldFromIndex(field);
            }

            FinalizeWriter(false);
        }

        #endregion

        #region Private methods
        

        private void DeleteFieldFromIndex<T>(T oldField) where T : BasicField
        {
            _indexWriter.DeleteDocuments(new Term(oldField.Name, oldField.Value));
        }

        private void InsertUpdateFieldFromIndex<T>(T newfield) where T : BasicField
        {
            AddFieldToIndex(newfield);
        }

        #endregion

        #endregion



        private Field MapElementToLuceneField(BasicField basicField)
        {
            Field.Store store = basicField.IsCompressed ? Field.Store.YES : Field.Store.NO;
            Field.Index index = basicField.IsSearchable ? Field.Index.ANALYZED : Field.Index.NOT_ANALYZED;
            Field field = new Field(basicField.Name, basicField.Value, store, index);
            return field;
        }

        private void FinalizeWriter(bool optimize)
        {
            if(optimize)
                _indexWriter.Optimize();
            _indexWriter.Commit();
            _indexWriter.Close();
        }

    }


}
